package io.geekidea.springbootplus.system.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils {

    private static RequestConfig requestConfig = null;
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录

    public static void isPathExistAndCreateDir(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    public static String getRootPath() {
        return System.getProperty("user.dir");
    }

    public static void readByte2File(byte[] byteArray, String targetPath) {
        InputStream in = new ByteArrayInputStream(byteArray);
        File file = new File(targetPath);
        String path = targetPath.substring(0, targetPath.lastIndexOf("/"));
        if (!file.exists()) {
            new File(path).mkdir();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != fos) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String doDelete(String url) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000).setConnectionRequestTimeout(35000).setSocketTimeout(60000).build();
        httpDelete.setConfig(requestConfig);
        httpDelete.setHeader("Content-type", "application/json");
        httpDelete.setHeader("DataEncoding", "UTF-8");
        // httpDelete.setHeader("token", token);

        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpDelete);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String doGet(String url) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        // httpGet.setHeader("token", token);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000).setConnectionRequestTimeout(35000).setSocketTimeout(60000).build();
        httpGet.setConfig(requestConfig);

        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpGet);

            httpResponse.setHeader("contentType", "text/html;charset=UTF-8");
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity, "utf-8");
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


    /**
     * 原生字符串发送post请求
     *
     * @param url
     * @param jsonStr
     * @return
     * @throws IOException
     */
    public static String doPost(String url, String jsonStr, boolean sendXml) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1200000).setConnectionRequestTimeout(1200000).setSocketTimeout(1200000).build();
        httpPost.setConfig(requestConfig);
        if (sendXml) {
            httpPost.setHeader("Content-type", "text/xml");
            httpPost.setHeader("Accept", "application/soap+xml");
        } else {
            httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
//            httpPost.setHeader("DataEncoding", "UTF-8");
        }

        //  httpPost.setHeader("token", token);

        CloseableHttpResponse httpResponse = null;
        httpPost.setEntity(new StringEntity(jsonStr));
        httpResponse = httpClient.execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();
        String result = EntityUtils.toString(entity);
        return result;
    }

    /**
     * 以post请求方式发送文件
     *
     * @param url
     * @param file 文件
     * @return 默认返回参数为Json格式的数据
     * @throws IOException
     * @throws InterruptedException
     */
    public static String postFile(String url, File file) {
        DataOutputStream out = null;
        BufferedReader in = null;
        String result = "";

        try {
            URL realUrl = new URL(url);
            // 打开和URL的连接
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            //发送POST必须设置如下两行
            conn.setDoInput(true);
            conn.setDoOutput(true);

            String BOUNDARY = "---------7d4a6d158c9"; //定义数据分割线
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
            conn.connect();

            out = new DataOutputStream(conn.getOutputStream());
            byte[] end_data = ("\r\n--" + BOUNDARY + "\r\n").getBytes(); //定义最后数据分割线
            //添加参数luid
            StringBuilder sb1 = new StringBuilder();
            sb1.append("--");
            sb1.append(BOUNDARY);
            sb1.append("\r\n");
            sb1.append("Content-Disposition: form-data;name=\"luid\"");
            sb1.append("\r\n");
            sb1.append("\r\n");
            sb1.append("123");
            sb1.append("\r\n");
            out.write(sb1.toString().getBytes());
            //添加参数file
            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"");
            sb1.append("\r\n");
            sb.append("Content-Type:application/octet-stream");
            sb1.append("\r\n");
            sb1.append("\r\n");
            out.write(sb.toString().getBytes());

            DataInputStream in1 = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in1.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            out.write("\r\n".getBytes()); //多个文件时，二者之间加入这个
            in1.close();
            out.write(end_data);

            //flush输入流的缓冲
            out.flush();
            //定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // finally关闭输入输出流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 原生字符串发送put请求
     *
     * @param url     // * @param token
     * @param jsonStr
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String doPut(String url, String jsonStr) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000).setConnectionRequestTimeout(35000).setSocketTimeout(60000).build();
        httpPut.setConfig(requestConfig);
        httpPut.setHeader("Content-type", "application/json");
        httpPut.setHeader("DataEncoding", "UTF-8");
        CloseableHttpResponse httpResponse = null;
        try {
            httpPut.setEntity(new StringEntity(jsonStr));
            httpResponse = httpClient.execute(httpPut);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String replaceAll3(String input, String regex, String replacement) {
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(input);
        String result = m.replaceAll(replacement);
        return result;
    }

    public static void doGetStr(String url) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            httpClient.execute(httpGet);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }


    public static StringBuffer sendWebService(String u, String xml) throws Exception {
        //拼接请求报文
        // 开启HTTP连接ַ
        InputStreamReader isr = null;
        BufferedReader inReader = null;
        StringBuffer result = null;
        OutputStream outObject = null;
        try {
            URL url = new URL(u);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

            // 设置HTTP请求相关信息
            httpConn.setRequestProperty("Content-Length",
                    String.valueOf(xml.getBytes().length));
            httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            httpConn.setRequestMethod("POST");
            httpConn.setDoOutput(true);
            httpConn.setDoInput(true);

            // 进行HTTP请求
            outObject = httpConn.getOutputStream();
            outObject.write(xml.getBytes());

            if (200 != (httpConn.getResponseCode())) {
                throw new Exception("HTTP Request is not success, Response code is " + httpConn.getResponseCode());
            }
            // 获取HTTP响应数据
            isr = new InputStreamReader(
                    httpConn.getInputStream(), "utf-8");
            inReader = new BufferedReader(isr);
            result = new StringBuffer();
            String inputLine;
            while ((inputLine = inReader.readLine()) != null) {
                result.append(inputLine);
            }
            return result;

        } catch (IOException e) {
            throw e;
        } finally {
            // 关闭输入流
            if (inReader != null) {
                inReader.close();
            }
            if (isr != null) {
                isr.close();
            }
            // 关闭输出流
            if (outObject != null) {
                outObject.close();
            }
        }

    }

    //拼接请求报文
    private static String appendXmlContext(String sid, String content, String tranSeq, String tranReqDate) {
        // 构建请求报文

        StringBuffer stringBuffer = new StringBuffer("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:com=\"http://com.foresee.top.service/\">\n" +
                "  <soapenv:Body>\n" +
                "    <ns1:doService xmlns:ns1=\"http://cn.gov.chinatax.gt3nf.nfzcpt.service/\">\n" +
                "      <reqXml><![CDATA[<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<tiripPackage xmlns:xsi=\"http://www.w3.org/2001/XMLSchema\" version=\"1.0\" xsi:type=\"tiripPackage\">\n" +
                "  <sessionId/>\n" +
                "  <service>\n" +
                "    <sid>" + sid + "</sid>\n" +
                "    <version>1.0</version>\n" +
                "    <tranSeq>+" + tranSeq + "</tranSeq>\n" +
                "    <tranReqDate>" + tranReqDate + "</tranReqDate>\n" +
                "  </service>\n" +
                "  <bizContent>\n" +
                "    <content>" + content + "</content>\n" +
                "    <paramList>\n" +
                "      <param>\n" +
                "        <name>docType</name>\n" +
                "        <value>json</value>\n" +
                "      </param>\n" +
                "      <param>\n" +
                "        <name>className</name>\n" +
                "        <value>GGG</value>\n" +
                "      </param>\n" +
                "    </paramList>\n" +
                "  </bizContent>\n" +
                "</tiripPackage>\n" +
                "]]></reqXml>\n" +
                "    </ns1:doService>\n" +
                "  </soapenv:Body>\n" +
                "</soapenv:Envelope>");
        return stringBuffer.toString();
    }

    public static <T> T obj2obj(Object object, Class<T> clazz) throws Exception {
        return JSON.parseObject(JSON.toJSONString(object), clazz);
    }

    public static String post(String URL,String json) {
        String obj = null;
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(URL);
        httppost.addHeader("Content-type", "application/json; charset=utf-8");
        httppost.setHeader("Accept", "application/json");
        try {
            StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));  //对参数进行编码，防止中文乱码
            s.setContentEncoding("UTF-8");
            httppost.setEntity(s);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                //获取相应实体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    obj = EntityUtils.toString(entity, "UTF-8");
                }

            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    public static String downloadFile(String path, HttpServletResponse response, String fileName) {
//        response.setCharacterEncoding("UTF-8");

        File file = new File(path);
        if (!file.exists()) {
            return "-1";
        }

        response.reset();

        if (fileName == null) {
            if (path.contains(".pdf") || path.contains(".png") || path.contains(".jpg") || path.contains(".jpeg")) {
                response.setHeader("Content-Disposition", "inline;fileName=" + path);

            } else {
                response.setHeader("Content-Disposition", "attachment;fileName=" + path);
            }
        } else {
//            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
            try {
                if (path.contains(".pdf") || path.contains(".png") || path.contains(".jpg")) {
                    response.setHeader("Content-Disposition", "inline;fileName=" + new String((fileName).getBytes("GBK"), "iso8859-1"));
                } else {
                    response.setHeader("Content-Disposition", "attachment;fileName=" + new String((fileName).getBytes("GBK"), "iso8859-1"));
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }


        response.setContentType("application/force-download");
        response.setContentType("multipart/form-data");
        if (path.contains(".pdf")) {
            response.setContentType("application/pdf");
        }else if(path.contains(".png") ){
            response.setContentType("image/png");
        }else if(path.contains(".jpg")){
            response.setContentType("image/jpg");
        }
//         url = URLEncoder.encode(url,"UTF-8");
        try {
            InputStream inStream = new FileInputStream(path);
            OutputStream os = response.getOutputStream();

            byte[] buff = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buff)) > 0) {
                os.write(buff, 0, len);
            }
            os.flush();
            os.close();

            inStream.close();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return "-2";
        }
    }

    public static String downloadFile(String path, HttpServletResponse response, String fileName, String type) {
        return downloadFile(path, response, fileName);
    }

    public static String downloadFile(String path, HttpServletResponse response) {
        return downloadFile(path, response, null);
    }
    public static String sendPost(String url, Map<String, Object> param, Map<String, String> headers, String encoding) {
        String rs = "{}";
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(url);
        // 创建参数队列
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        for (String key : param.keySet()) {
            formparams.add(new BasicNameValuePair(key, param.get(key).toString()));
        }
        // 设置头信息
        if (headers != null) {
            for (String key : headers.keySet()) {
                httppost.setHeader(key, headers.get(key));
            }
        }
        UrlEncodedFormEntity uefEntity;
        try {
            uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
            httppost.setEntity(uefEntity);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    rs = EntityUtils.toString(entity, "UTF-8");
                }
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return rs;
    }

    public static JSONObject httpPost(String url, JSONObject jsonParam)
    {
        // post请求返回结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);
        try
        {
            if (null != jsonParam)
            {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            CloseableHttpResponse result = httpClient.execute(httpPost);
            // 请求发送成功，并得到响应
            if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
            {
                String str = "";
                try
                {
                    // 读取服务器返回过来的json字符串数据
                    str = EntityUtils.toString(result.getEntity(), "utf-8");
                    // 把json字符串转换成json对象
                    jsonResult = JSONObject.parseObject(str);
                }
                catch (Exception e)
                {
                    e.printStackTrace();

                    logger.error("post请求提交失败:" + url, e);
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            httpPost.releaseConnection();
        }
        return jsonResult;
    }
}
